import wx, wx.aui, sys
import os, json
import os.path as osp
sys.path.append('../')
from riseide.consoles import ConsoleBook
from riseide.workspace import WorkSpace
from riseide.codepad import CodePad
from riseide.docpad import DocPad
from riseide.catlog import TreeView
from riseide.toolbar import ToolBar
from riseide.notebook import ObjectNoteBook

from riseide.plugins.search_widget import SearchPanel

def read_txt(path):
    with open(path, encoding='utf-8') as f: return f.read()


ReaderManager = {'py': (read_txt, 'code'), 
                 'html': (read_txt, 'doc')}

class MiniFrame ( wx.Frame ):
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = "重鸣软件-RiseIDE", pos = wx.DefaultPosition, size = wx.Size( 1024,768 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetIcon(wx.Icon('./icons/riseup.ico', wx.BITMAP_TYPE_ICO))
        self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
        self.m_mgr = wx.aui.AuiManager()
        self.m_mgr.SetManagedWindow( self )
        self.m_mgr.SetFlags(wx.aui.AUI_MGR_DEFAULT)

        self.toolbar = ToolBar(self)
        self.init_toolbar()
        self.m_mgr.AddPane( self.toolbar, wx.aui.AuiPaneInfo().Top().CaptionVisible( False ).PinButton( True ).Dock().Resizable().FloatingSize( wx.DefaultSize ).Layer( 10 ) )
        
        # self.searchpad = SearchPanel(self)
        # self.m_mgr.AddPane( self.searchpad, wx.aui.AuiPaneInfo().Top().CaptionVisible( False ).PinButton( True ).Dock().Resizable().FloatingSize( wx.DefaultSize ).Layer( 5 ) )

        self.catlog = TreeView(self, style = wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_DEFAULT_STYLE|wx.TR_NO_LINES|wx.TR_TWIST_BUTTONS|wx.TR_MULTIPLE|wx.TR_FULL_ROW_HIGHLIGHT)
        if osp.exists('./config.json'):
            with open('./config.json') as f: self.catlog.roots = json.load(f)
        self.catlog.RefreshItems()
        self.catlog.SetHandler(self.on_open)
        self.m_mgr.AddPane( self.catlog, wx.aui.AuiPaneInfo() .Caption( '项目管理' ) .Left() .PinButton( True ).Dock().Resizable().FloatingSize( wx.DefaultSize ).BestSize( wx.Size( 256,-1 ) ).Layer( 1 ) )

        panel = wx.Panel(self); sizer = wx.BoxSizer( wx.VERTICAL ); self.page = ObjectNoteBook(panel)
        sizer.Add( self.page, 1, wx.EXPAND |wx.ALL, 0 ); panel.SetSizer( sizer )
        self.m_mgr.AddPane( panel, wx.aui.AuiPaneInfo() .Center() .PinButton( True ).Dock().Resizable().CaptionVisible( False ).FloatingSize( wx.DefaultSize ) )

        self.workspace = WorkSpace(self)
        self.m_mgr.AddPane( self.workspace, wx.aui.AuiPaneInfo() .Caption( '工作区' ) .Right() .PinButton( True ).Dock().Resizable().FloatingSize( wx.DefaultSize ).BestSize( wx.Size( 256,-1 ) ).Layer( 1 ) )

        self.console = ConsoleBook(self)
        self.console.reference(self.workspace)
        self.m_mgr.AddPane( self.console, wx.aui.AuiPaneInfo() .Caption( '控制台' ) .Bottom() .PinButton( True ).Dock().Resizable().FloatingSize( wx.Size( -1,-1 ) ).BestSize( wx.Size( -1,200 ) ) )

        self.m_mgr.Update()
        self.Centre( wx.BOTH )

        self.Bind(wx.EVT_CLOSE, self.exit)
        self.page.Bind( wx.lib.agw.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_note)

        self.status_bar = self.CreateStatusBar( 3, wx.STB_SIZEGRIP, wx.ID_ANY )
        self.status_bar.SetStatusWidths([-1, 100, 100])
        self.status_bar.SetStatusText('重鸣软件-RiseIDE V0.1', 0)
        
        self.on_open('doc/readme.html', True)
        

    def init_toolbar(self): 
        from riseide.plugins import code_plugin as plg
        tools = [('文件', None, [('新建', './icons/新建@1x.png', plg.NewFile),
                                 ('打开', './icons/打开文件@1x.png', plg.OpenFile),
                                 ('打开文件夹', './icons/打开文件夹@1x.png', plg.OpenDir),
                                 ('保存', './icons/保存@1x.png', plg.SaveFile)]),
                 #'-',
                 ('编辑', None, [('复制', './icons/复制@1x.png', plg.Copy), 
                                 ('剪切', './icons/剪切@1x.png', plg.Cut), 
                                 ('粘贴', './icons/粘贴@1x.png', plg.Paste), 
                                 ('查找', './icons/查找@1x.png', plg.Search), 
                                 ('替换', './icons/替换@1x.png', plg.Search)]), 
                 #'-',
                 ('运行', None, [('运行', './icons/运行@1x.png', plg.ExecFile),
                                ('终止', './icons/终止@1x.png', plg.Terminate)]),
                 #'-',
                 ('排版', None, [('左缩进', './icons/左缩进@1x.png', plg.Dedent), 
                                 ('右缩进', './icons/右缩进@1x.png', plg.Indent), 
                                 ('加注释', './icons/加注释@1x.png', plg.Comment), 
                                 ('去注释', './icons/去注释@1x.png', plg.UnComment), 
                                 ('PEP8', './icons/PEP8@1x.png', plg.SelectAll)]), 
                 #'-',
                 ('调试', None, [('调试', './icons/调试.png', plg.Debug),
                                 ('继续', './icons/继续.png', plg.DebugContinue),
                                 ('下一行', './icons/下一步.png', plg.DebugNext),
                                 ('跳入', './icons/跳入.png', plg.DebugInto),
                                 ('跳出', './icons/跳出.png', plg.DebugOut),
                                 ('停止', './icons/停止.png', plg.DebugStop)])]
        
        hotkeys = {'新建':'Ctrl-N', '保存':'Ctrl-S', '查找':'Ctrl-F'}
        self.toolbar.load(tools, hotkeys)
        self.run_button_enable([1,1,1,0,0,0,0,0])

    def run_button_enable(self, status):
        labels = ['运行', '终止', '调试', '继续', '下一行', '跳入', '跳出', '停止']
        for lab, sta in zip(labels, status): self.toolbar.enable(lab, sta)
        self.toolbar.Refresh()

    def on_open(self, path, fixed):
        if self.page.active_by_path(path, fixed): return
        name, ext = osp.splitext(path)
        reader = ReaderManager.get(ext[1:].lower(), None)
        if reader is None: 
            print('未知格式，无法打开')
            return
        read, tag = reader
        self.show_obj(read(path), path, tag, fixed)

    def on_close_note(self, event):
        view = event.GetEventObject().GetPage(event.GetSelection())
        view.OnClose(event)

    def info(self, s1=None, s2=None, s3=None):
        if s1 != None: self.SetStatusText(s1, 0)
        if s2 != None: self.SetStatusText(s2, 1)
        if s3 != None: self.SetStatusText(s3, 2)

    def get_path(self, title, filt, io, name=''):
        if isinstance(filt, str): filt = filt.split(',')
        filt = '|'.join(['%s files (*.%s)|*.%s'%(i.upper(),i,i) for i in filt])
        dic = {'open':wx.FD_OPEN, 'save':wx.FD_SAVE}
        if io in {'open', 'save'}:
            dialog = wx.FileDialog(self, title, '', name, filt, dic[io] | wx.FD_CHANGE_DIR)
        else: dialog = wx.DirDialog(self, title, '', wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST | wx.FD_CHANGE_DIR)
        rst = dialog.ShowModal()
        path = dialog.GetPath() if rst == wx.ID_OK else None
        dialog.Destroy()
        return path

    def show_obj(self, obj, path, tag, fixed):
        if tag=='code':
            self.show_code(obj, path, fixed=fixed)
        if tag=='doc':
            self.show_doc(obj, path, fixed=fixed)
        if tag=='img':
            self.show_img(obj, path, fixed=fixed)
        if tag=='tab':
            self.show_table(obj, path, fixed=fixed)

    def _show_code(self, cont, path, name, fixed):
        if path != None: name = osp.split(path)[-1]
        codepd = CodePad(self.page, (cont, name, path))
        page = self.page.add_page(codepd, fixed)

    def show_code(self, code, path=None, name='new_script.py', fixed=False):
        wx.CallAfter(self._show_code, code, path, name, fixed)
    
    def _show_doc(self, cont, path, name, fixed):
        if path != None: name = osp.split(path)[-1]
        docpad = DocPad(self.page, (cont, name, path))
        page = self.page.add_page(docpad, fixed)
        
    def show_doc(self, doc, path=None, name='', fixed=False):
        wx.CallAfter(self._show_doc, doc, path, name, fixed)

    def __del__( self ):
        self.m_mgr.UnInit()
    
    def exit(self, event):
        self.console.terminate_all()
        print(self.catlog.roots)
        with open('./config.json', 'w') as f:
            rst = [[i[0], False, None if i[2] is None else [[\
                '', False, None]]] for i in self.catlog.roots[2]]
            self.catlog.roots[2] = rst
            json.dump(self.catlog.roots, f)
        os._exit(0)

if __name__ == '__main__':
    app = wx.App()
    frame = MiniFrame(None)
    frame.Show()
    app.MainLoop()

    # debug('./debug/test.py')
